

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.comm.CommPortIdentifier;
import javax.comm.CommDriver;
import java.util.Enumeration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

public class Host extends JFrame {

    private HashMap<String, CommPortIdentifier> cpiMap = new HashMap<String, CommPortIdentifier>();
    protected static ArrayList<Robot> robotList = new ArrayList<Robot>();
    private HostDBComm dbcomm = new HostDBComm();

    public Host(){
        JButton jbtnClose = new JButton("close");
        this.add(jbtnClose);
        jbtnClose.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent ae){
                for(int i = 0; i < robotList.size(); i++)
                    robotList.get(i).stop();
                dbcomm.disconnect();
                System.exit(0);
            }
        });
        dbcomm.connect();
        //FrameGrabber frameGrabber = new FrameGrabber(dbcomm, 2000);
        //new Thread(frameGrabber).start();
    }

    public static void main(String[] args) {

        Host h = new Host();
        h.setSize(400, 400);
        h.setLocationRelativeTo(null);
        h.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        h.setVisible(true);
        QueueHost queueHost = new QueueHost();
        new Thread(queueHost).start();
        h.initCommPorts();
        if(h.findRobots()) h.init();

    }

    private class FrameGrabber implements Runnable {
        private File file = new File("C://Program Files//VideoLAN//VLC//frame.jpeg");
        private HostDBComm dbcomm;
        private boolean stop = false;
        private int delay;

        public FrameGrabber(HostDBComm comm, int d) {
            this.dbcomm = comm;
            this.delay = d;
        }
        public void run() {
            while (!stop) {
                dbcomm.uploadFrame(file);
                try {
                    Thread.sleep(delay);
                } catch (InterruptedException ex) {
                    continue;
                }
            }
        }

    }

    private void initCommPorts() {
        try {
            CommDriver commDriver = (CommDriver) Class.forName("com.sun.comm.Win32Driver").newInstance();
            commDriver.initialize();
            Enumeration pList = CommPortIdentifier.getPortIdentifiers();

            while (pList.hasMoreElements()) {
                CommPortIdentifier cpi = (CommPortIdentifier) pList.nextElement();
                String name = cpi.getName();
                if(name.startsWith("COM") && !cpiMap.containsKey(name)){
                    cpiMap.put(name, cpi);
                }
            }
        } catch (Exception ex){ex.printStackTrace();}
    }

    private boolean findRobots() {                
        int robotCount = 1;
        System.out.println("Find Robots");
        Iterator it = cpiMap.keySet().iterator();
        while(it.hasNext()) {
            CommPortIdentifier cpi = cpiMap.get(it.next());
            String name = cpi.getName();
            System.out.print("Searching " + name + "...");
            try{
                robotList.add(createRobot("Robot" + robotCount, new RobotComm("RobotComm" + robotCount, cpi), robotCount++));
                System.out.println("Connected using " + name);
            }
            catch(Exception ex){
                System.err.println("Error: " + name);
                ex.printStackTrace();
            }
        }
        System.out.println("Search Complete");
        if(!robotList.isEmpty())return true;
        else return false;
    }

    private Robot createRobot(String robotID, RobotComm robotComm, int robotCount){
        char initHeading = '\0';
        Point initPoint = null;
        int[] path = null;
        switch(robotCount){
            case 1: initHeading = 'N'; initPoint = new Point(0,0); path = new int[]{0,1,1}; break;
            case 2: initHeading = 'S'; initPoint = new Point(0,5); path = new int[]{1,1,0}; break;
            case 3: initHeading = 'S'; initPoint = new Point(5,5); path = new int[]{0,1,1}; break;
            case 4: initHeading = 'N'; initPoint = new Point(5,0); path = new int[]{1,1,0}; break;
        }
        return new Robot(robotID, robotComm, initHeading, initPoint, path);
    }

    private void init(){        
        for(int i = 0; i < robotList.size(); i++){
            robotList.get(i).initRobot();
            robotList.get(i).initDB();
            new Thread(robotList.get(i)).start();
        }
    }

}
